// Package config 提供配置加载功能
package config

import (
	"fmt"
	"os"
	"strings"

	"github.com/cnssl/cert-deploy-iis/internal/errors"
)

// Config 应用配置
type Config struct {
	// API 配置
	APIURL   string // 证书 API 地址
	APIToken string // Bearer Token

	// 证书校验（可选）
	Domain string // 期望的证书域名，为空则跳过校验

	// 部署路径
	KeyPath string // 私钥文件路径
	CrtPath string // 证书文件路径
	CAPath  string // CA 证书路径

	// Reload 命令
	ReloadCmd string // 例如: "systemctl reload nginx"

	// 日志级别
	LogLevel string // debug|info|warn|error
}

// Load 从环境变量加载配置
func Load() (*Config, error) {
	cfg := &Config{
		APIURL:    os.Getenv("CERT_API_URL"),
		APIToken:  os.Getenv("CERT_API_TOKEN"),
		Domain:    os.Getenv("CERT_DOMAIN"),
		KeyPath:   os.Getenv("CERT_KEY_PATH"),
		CrtPath:   os.Getenv("CERT_CRT_PATH"),
		CAPath:    os.Getenv("CERT_CA_PATH"),
		ReloadCmd: os.Getenv("RELOAD_CMD"),
		LogLevel:  getEnvWithDefault("LOG_LEVEL", "info"),
	}

	if err := cfg.Validate(); err != nil {
		return nil, err
	}

	return cfg, nil
}

// Validate 校验配置
func (c *Config) Validate() error {
	var missing []string

	if c.APIURL == "" {
		missing = append(missing, "CERT_API_URL")
	}
	if c.APIToken == "" {
		missing = append(missing, "CERT_API_TOKEN")
	}
	if c.KeyPath == "" {
		missing = append(missing, "CERT_KEY_PATH")
	}
	if c.CrtPath == "" {
		missing = append(missing, "CERT_CRT_PATH")
	}
	if c.CAPath == "" {
		missing = append(missing, "CERT_CA_PATH")
	}
	if c.ReloadCmd == "" {
		missing = append(missing, "RELOAD_CMD")
	}

	if len(missing) > 0 {
		return errors.NewConfigError(
			fmt.Sprintf("missing required environment variables: %s", strings.Join(missing, ", ")),
			nil,
		)
	}

	// 验证日志级别
	validLevels := map[string]bool{"debug": true, "info": true, "warn": true, "error": true}
	if !validLevels[strings.ToLower(c.LogLevel)] {
		return errors.NewConfigError(
			fmt.Sprintf("invalid LOG_LEVEL: %s (must be debug|info|warn|error)", c.LogLevel),
			nil,
		)
	}

	return nil
}

// getEnvWithDefault 获取环境变量，提供默认值
func getEnvWithDefault(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}
